package cvi.com.reader.uploadrecord;

import android.util.Log;

import java.io.File;
import java.io.IOException;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.internal.Util;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ForwardingSink;
import okio.ForwardingSource;
import okio.Okio;
import okio.Sink;
import okio.Source;

public class ProgressRequestBody extends RequestBody {
    //实际的待包装请求体
    // private final RequestBody requestBody;
    //进度回调接口
    private final ProgressListener progressListener;
    //包装完成的BufferedSink
    private BufferedSink bufferedSink;
    private File file = null;
    private MediaType contentType;

    public ProgressRequestBody(MediaType contentType, File file, ProgressListener progressListener) {
        this.progressListener = progressListener;
        this.file = file;
        this.contentType = contentType;
    }

    public ProgressRequestBody(File file, ProgressListener progressListener) {
        this.file = file;
        this.progressListener = progressListener;
    }

    /**
     * 重写调用实际的响应体的contentType
     *
     * @return MediaType
     */
    @Override
    public MediaType contentType() {
        return contentType;
    }

    /**
     * 重写调用实际的响应体的contentLength
     *
     * @return contentLength
     * @throws IOException 异常
     */
    @Override
    public long contentLength() throws IOException {
        return file.length();
    }

    private Source source(Source source) {
        return new ForwardingSource(source) {
            long totalBytesRead = 0L;

            @Override
            public long read(Buffer sink, long byteCount) throws IOException {
                long bytesRead = super.read(sink, byteCount);
                totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                progressListener.onProgress(totalBytesRead, file.length(), bytesRead == file.length());
                return bytesRead;
            }
        };
    }

    /**
     * 重写进行写入
     *
     * @param sink BufferedSink
     * @throws IOException 异常
     */
    @Override
    public void writeTo(BufferedSink sink) throws IOException {
      /*  if (null == bufferedSink) {
           bufferedSink = Okio.buffer(sink(sink));

        }*/
        if (null == bufferedSink) {
            bufferedSink = Okio.buffer(sink(sink));

        }
        Source source = null;
        try {
            source = Okio.source(file);
            bufferedSink.writeAll(source);
        } finally {

            Util.closeQuietly(source);
        }
        bufferedSink.flush();
     /*
        this.writeTo(bufferedSink);
        //必须调用flush，否则最后一部分数据可能不会被写入
        bufferedSink.flush();*/
    }

    /**
     * 写入，回调进度接口
     *
     * @param sink Sink
     * @return Sink
     */
    private Sink sink(Sink sink) {

        return new ForwardingSink(sink) {
            //当前写入字节数
            long bytesWritten = 0L;
            //总字节长度，避免多次调用contentLength()方法
            long contentLength = 0L;

            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                Log.d("chris", "currentBytes:fsfd1111");
                if (contentLength == 0) {
                    //获得contentLength的值，后续不再调用
                    contentLength = contentLength();
                }
                Log.d("chris", "currentBytes:fsfd22222");
                //增加当前写入的字节数
                bytesWritten += byteCount;
                //回调
                if (progressListener != null) {
                    Log.d("chris", "currentBytes:fsfd33333");
                    progressListener.onProgress(bytesWritten, contentLength, bytesWritten == contentLength);
                }

            }
        };
    }
}